﻿using Lhz.InternetService;
using Lhz.Sc.Business;
using Lhz.Sc.Entity.Exception;
using Lhz.Sc.Entity.Interface;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;

namespace Lhz.Sc.Test.LhzScService
{
    [TestClass]
    public class UnitTestServiceCenter
    {
        private UserProxy uo = new UserProxy();
        private LogProxy lo = new LogProxy();
        private ServiceProxy so = new ServiceProxy();
        private ServiceInvoker si = new ServiceInvoker() { AllowCookie = true };

        [TestMethod]
        public void ServiceCenterWcfServiceTestMethodLogin()
        {
            var user = uo.Query().Where(r => !r.IsAdmin).First();
            si.Invoke(TestConst.ServiceServiceCenterWcfUrl, "Login", user.Username, user.Password);
            try
            {
                si.Invoke(TestConst.ServiceServiceCenterWcfUrl, "Login", user.Username, user.Password + Guid.NewGuid());
                Assert.Fail();
            }
            catch (Exception e)
            {
                Assert.AreEqual(e.InnerException.Message, new UsernameOrPasswordErrorException().Message);
            }
        }

        [TestMethod]
        public void ServiceCenterWcfServiceTestMethodInvokeWithWrongApplicationNo()
        {
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => !r.IsAdmin);
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No + Guid.NewGuid(),
                ServiceNo = service.No,
                OperationNo = operationNo
            };

            si.Invoke(TestConst.ServiceServiceCenterWcfUrl, "Login", user.Username, user.Password);
            try
            {
                si.Invoke(TestConst.ServiceServiceCenterWcfUrl, "InvokeByJsonInvokeArgument", ia);
                Assert.Fail();
            }
            catch (Exception e)
            {
                Assert.AreEqual(e.InnerException.Message, new InvokeException(ia.ApplicationNo, ia.ServiceNo, ia.OperationNo).Message);
            }

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }

        [TestMethod]
        public void ServiceCenterWcfServiceTestMethodInvokeWithWrongServiceNo()
        {
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => !r.IsAdmin);
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No,
                ServiceNo = service.No + Guid.NewGuid(),
                OperationNo = operationNo
            };

            si.Invoke(TestConst.ServiceServiceCenterWcfUrl, "Login", user.Username, user.Password);
            try
            {
                si.Invoke(TestConst.ServiceServiceCenterWcfUrl, "InvokeByJsonInvokeArgument", ia);
                Assert.Fail();
            }
            catch (Exception e)
            {
                Assert.AreEqual(e.InnerException.Message, new InvokeException(ia.ApplicationNo, ia.ServiceNo, ia.OperationNo).Message);
            }

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }

        [TestMethod]
        public void ServiceCenterWcfServiceTestMethodInvokeWithWrongOperationNo()
        {
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => !r.IsAdmin);
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No,
                ServiceNo = service.No,
                OperationNo = operationNo + Guid.NewGuid()
            };

            si.Invoke(TestConst.ServiceServiceCenterWcfUrl, "Login", user.Username, user.Password);
            try
            {
                si.Invoke(TestConst.ServiceServiceCenterWcfUrl, "InvokeByJsonInvokeArgument", ia);
                Assert.Fail();
            }
            catch (Exception e)
            {
                Assert.AreEqual(e.InnerException.Message, new InvokeException(ia.ApplicationNo, ia.ServiceNo, ia.OperationNo).Message);
            }

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }

        [TestMethod]
        public void ServiceCenterWcfServiceTestMethodInvoke()
        {
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => r.Username == "liuhongzhe");
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No,
                ServiceNo = service.No,
                OperationNo = operationNo,
                Arguments = new string[] { null }
            };

            si.Invoke(TestConst.ServiceServiceCenterWcfUrl, "Login", user.Username, user.Password);
            si.Invoke(TestConst.ServiceServiceCenterWcfUrl, "InvokeByJsonInvokeArgument", ia);

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }

        [TestMethod]
        public void ServiceCenterWebServiceTestMethodLogin()
        {
            var user = uo.Query().Where(r => !r.IsAdmin).First();
            si.Invoke(TestConst.ServiceServiceCenterWebServiceUrl, "Login", user.Username, user.Password);
            try
            {
                si.Invoke(TestConst.ServiceServiceCenterWebServiceUrl, "Login", user.Username, user.Password + Guid.NewGuid());
                Assert.Fail();
            }
            catch (Exception e)
            {
                Assert.IsTrue(e.InnerException.Message.Contains(new UsernameOrPasswordErrorException().Message));
            }
        }

        [TestMethod]
        public void ServiceCenterWebServiceTestMethodInvokeWithWrongApplicationNo()
        {
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => !r.IsAdmin);
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No + Guid.NewGuid(),
                ServiceNo = service.No,
                OperationNo = operationNo
            };

            si.Invoke(TestConst.ServiceServiceCenterWebServiceUrl, "Login", user.Username, user.Password);
            try
            {
                si.Invoke(TestConst.ServiceServiceCenterWebServiceUrl, "InvokeByJsonInvokeArgument", ia);
                Assert.Fail();
            }
            catch (Exception e)
            {
                Assert.IsTrue(e.InnerException.Message.Contains(new InvokeException(ia.ApplicationNo, ia.ServiceNo, ia.OperationNo).Message));
            }

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }

        [TestMethod]
        public void ServiceCenterWebServiceTestMethodInvokeWithWrongServiceNo()
        {
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => !r.IsAdmin);
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No,
                ServiceNo = service.No + Guid.NewGuid(),
                OperationNo = operationNo
            };

            si.Invoke(TestConst.ServiceServiceCenterWebServiceUrl, "Login", user.Username, user.Password);
            try
            {
                si.Invoke(TestConst.ServiceServiceCenterWebServiceUrl, "InvokeByJsonInvokeArgument", ia);
                Assert.Fail();
            }
            catch (Exception e)
            {
                Assert.IsTrue(e.InnerException.Message.Contains(new InvokeException(ia.ApplicationNo, ia.ServiceNo, ia.OperationNo).Message));
            }

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }

        [TestMethod]
        public void ServiceCenterWebServiceTestMethodInvokeWithWrongOperationNo()
        {
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => !r.IsAdmin);
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No,
                ServiceNo = service.No,
                OperationNo = operationNo + Guid.NewGuid()
            };

            si.Invoke(TestConst.ServiceServiceCenterWebServiceUrl, "Login", user.Username, user.Password);
            try
            {
                si.Invoke(TestConst.ServiceServiceCenterWebServiceUrl, "InvokeByJsonInvokeArgument", ia);
                Assert.Fail();
            }
            catch (Exception e)
            {
                Assert.IsTrue(e.InnerException.Message.Contains(new InvokeException(ia.ApplicationNo, ia.ServiceNo, ia.OperationNo).Message));
            }

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }

        [TestMethod]
        public void ServiceCenterWebServiceTestMethodInvoke()
        {
            var operationNo = "query";

            lo.Delete(lo.Query());
            var logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);

            var user = uo.Query().First(r => r.Username == "liuhongzhe");
            var service = so.Query().First(r => r.Application.No == "Sc" && r.No == "user");
            var application = service.Application;
            var ia = new InvokeArgument()
            {
                ApplicationNo = application.No,
                ServiceNo = service.No,
                OperationNo = operationNo,
                Arguments = new string[] { null }
            };

            si.Invoke(TestConst.ServiceServiceCenterWebServiceUrl, "Login", user.Username, user.Password);
            si.Invoke(TestConst.ServiceServiceCenterWebServiceUrl, "InvokeByJsonInvokeArgument", ia);

            logs = lo.Query();
            Assert.AreEqual(logs.Count, 1);
            var log = logs.First();
            Assert.AreEqual(log.UserGuid, user.Guid);
            Assert.IsTrue(log.InvokeResult.Contains(service.No));
            Assert.IsTrue(log.InvokeResult.Contains(operationNo));

            lo.Delete(log);
            logs = lo.Query();
            Assert.AreEqual(logs.Count, 0);
        }
    }
}
